﻿using CNKI.TPI.Web.Base;
using CNKI.TPI.Web.Interface.Models;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Security.Cryptography;
using System.Text;
using System.Web;
using System.Web.Http;
using System.Web.Http.Controllers;

namespace CNKI.TPI.Web.Interface.Filters
{
    public class CustWebApiAuthAttribute : AuthorizeAttribute
    {

        protected override bool IsAuthorized(HttpActionContext httpContext)
        {
            bool result = false;
            try
            {
                string from = null;
                string secret = null;
                string sign = null;
                ArrayList list = new ArrayList();

                //获得参数
                if (HttpMethod.Get == httpContext.Request.Method)
                {
                    IEnumerable<KeyValuePair<string, string>> parameters = httpContext.Request.GetQueryNameValuePairs();
                    foreach (KeyValuePair<string, string> item in parameters)
                    {
                        if ("sign".Equals(item.Key))
                        {
                            sign = item.Value;
                        }
                        else if (!string.IsNullOrEmpty(item.Value))
                        {
                            list.Add(item.Value);
                        }

                        if ("from".Equals(item.Key))
                        {
                            from = item.Value;
                        }
                    }
                }
                else if (HttpMethod.Post == httpContext.Request.Method)
                {
                    HttpContextBase context = (HttpContextBase)httpContext.Request.Properties["MS_HttpContext"];//获取传统context     
                    HttpRequestBase request = context.Request;//定义传统request对象
                    foreach (string key in request.Form.AllKeys)
                    {
                        if ("sign".Equals(key))
                        {
                            sign = request.Form[key];
                        }
                        else if (!string.IsNullOrEmpty(request.Form[key]))
                        {
                            list.Add(request.Form[key]);
                        }

                        if ("from".Equals(key))
                        {
                            from = request.Form[key];
                        }
                    }
                }

                //获得指定from的secretKey
                if (!string.IsNullOrEmpty(from) && !string.IsNullOrEmpty(sign))
                {
                    secret = ConfigHelper.GetAccessConfig(from);
                }
                if (!string.IsNullOrEmpty(secret))
                {
                    //排序
                    list.Add(secret);
                    list.Sort();
                    StringBuilder str_signing = new StringBuilder();
                    foreach (string item in list)
                    {
                        str_signing.Append(item);
                    }
                    //生成签名
                    string signresult = GeneralSign(str_signing.ToString());
                    //验证签名
                    if (signresult.Equals(sign))
                    {
                        result = true;
                    }
                }
            }
            catch (Exception ex)
            {
                LogOpr.Error(ex.ToString());
            }
            return result;
        }

        private static string GeneralSign(string content)
        {
            // 第三步：使用MD5加密
            MD5 md5 = MD5.Create();
            byte[] bytes = md5.ComputeHash(Encoding.UTF8.GetBytes(content));

            // 第四步：把二进制转化为大写的十六进制
            StringBuilder result = new StringBuilder();
            for (int i = 0; i < bytes.Length; i++)
            {
                result.Append(bytes[i].ToString("X2"));
            }
            return result.ToString();
        }

        protected override void HandleUnauthorizedRequest(HttpActionContext actionContext)
        {
            OutputEntity oe = new OutputEntity();
            oe.Status = Status.AuthenticationFailed;
            actionContext.Response = actionContext.Request.CreateResponse();
            actionContext.Response.Content = new StringContent(SerializeHelper.Serialize(oe));
        }
    }
}